package opencm;

import java.io.Serializable;
import java.util.UUID;

import org.apache.commons.lang3.Validate;
import org.joda.time.LocalDate;

/**
 * Um Paciente.
 */
public final class Paciente implements Serializable {

	private final UUID id;
	private int codigo;
	private Perfil perfil;
	private PlanoSaude planoSaude;

	private LocalDate dataUltimaVisita = null;

	private static final long serialVersionUID = 1L;

	/**
	 * Construtor unico de Paciente.
	 * @param codigo Codigo do paciente.
	 * @param perfil Perfil do paciente.
	 * @param planoSaude Plano de Saude do paciente.
	 */
	public Paciente(int codigo, Perfil perfil, PlanoSaude planoSaude) {
		setCodigo(codigo);
		setPerfil(perfil);
		setPlanoSaude(planoSaude);
		this.id = UUID.randomUUID();
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if (obj == this)
			return true;
		if (obj instanceof Paciente) {
			Paciente p = (Paciente) obj;
			return p.id().equals(id());
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return id().hashCode();
	}
	
	@Override
	public String toString() {
		return getPerfil().getNome();
	}

	/**
	 * Retorna o id do paciente.
	 * @return UUID
	 */
	public UUID id() {
		return this.id;
	}

	/**
	 * Muda o codigo do paciente.
	 * @param codigo Novo codigo.
	 */
	public void setCodigo(int codigo) {
		Validate.isTrue(codigo >= 0, "Código Inválido.");
		this.codigo = codigo;
	}

	/**
	 * Muda o perfil do paciente.
	 * @param perfil Novo perfil.
	 */
	public void setPerfil(Perfil perfil) {
		Validate.notNull(perfil, "Perfil não pode ser nulo.");
		this.perfil = perfil;
	}

	/**
	 * Muda o plano de saude do paciente.
	 * @param planoSaude Novo plano de saude.
	 */
	public void setPlanoSaude(PlanoSaude planoSaude) {
		Validate.notNull(planoSaude, "Plano de Saúde não pode ser nulo.");
		this.planoSaude = planoSaude;
	}

	/**
	 * Muda a data da ultima visita do paciente.
	 * @param ultimaVisita Nova data.
	 */
	public void setDataUltimaVisita(LocalDate ultimaVisita) {
		this.dataUltimaVisita = ultimaVisita;
	}

	/**
	 * Retorna o codigo do paciente.
	 * @return Codigo
	 */
	public int getCodigo() {
		return this.codigo;
	}

	/**
	 * Retorna o perfil do paciente.
	 * @return Perfil
	 */
	public Perfil getPerfil() {
		return this.perfil;
	}

	/**
	 * Retorna o plano de saude do paciente.
	 * @return Plano de saude
	 */
	public PlanoSaude getPlanoSaude() {
		return this.planoSaude;
	}

	/**
	 * Retorna o local da ultima visita do paciente.
	 * @return
	 */
	public LocalDate getDataUltimaVisita() {
		return this.dataUltimaVisita;
	}
	
}
